const path = require('path')
const resolve = (dir) => path.resolve(__dirname, dir)
const CompressionWebpackPlugin = require('compression-webpack-plugin')
// const CopyWebpackPlugin = require('copy-webpack-plugin')
const BundleAnalyzerPlugin =
  require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i

function changeHtmlWebpackPluginChunks(config) {
  const plugins = config.plugins
  // 这里要和下面的optimization.splitChunks分离出来的对应好，否则无法引入
  const chunkArr = ['runtime', 'chunk-vant', 'chunk-vendor', 'chunk-commons']

  plugins.forEach((item, index) => {
    // 找到HtmlWebpackPlugin
    if (
      item.options &&
      Object.prototype.toString.call(item.options) === '[object Object]' &&
      Object.hasOwnProperty.call(item.options, 'filename') &&
      Object.hasOwnProperty.call(item.options, 'chunks') &&
      item.options.filename === 'index.html'
    ) {
      const oldChunks = item.options.chunks || []
      // 修改chunks引入
      item.options.chunks = [...chunkArr, ...oldChunks]
    }
  })
}

module.exports = {
  // 部署应用包时的基本url
  publicPath: '/',
  // 打包后生成的生产环境构建文件的目录
  outputDir: 'dist',
  // 是否开启 eslint 认证
  lintOnSave: false,
  // 放置生成的静态资源
  assetsDir: 'assets',
  // 指定生成的输出路径
  indexPath: 'index.html',
  // 生成的静态资源在它们的文件名中包含了 hash 以便更好的控制缓存
  filenameHashing: true,
  // 配置类型是Object 这也是多页面应用的所需要配置的
  pages: {
    index: {
      entry: 'src/main.js',
      // 模板来源
      template: 'public/index.html',
      filename: 'index.html',
      title: '大连市校园疫情防控系统',
      chunks: ['chunk-vendors', 'chunk-common', 'index'],
    },
  },
  // 是否使用包含运行时编译器的 Vue 构建版本
  runtimeCompiler: false,
  // 打包时不生成.map文件
  productionSourceMap: false,
  // Babel 显式转译列表
  transpileDependencies: ['sl-vue-tre'],
  css: {
    // 是否使用css分离插件 ExtractTextPlugin
    extract: false,
    // 开启 CSS source maps?是否在构建样式地图，false将提高构建速度
    sourceMap: false,
    // css预设器配置项
    loaderOptions: {},
    // 启用 CSS modules for all css / pre-processor files
    modules: false,
  },

  devServer: {
    open: false, // 配置自动启动浏览器
    host: '0.0.0.0', // 设置主机地址
    port: 8080, // 端口号
    hotOnly: false, // 热更新
    compress: true,
    https: false,
    overlay: {
      warnings: true,
      errors: true,
    },
    proxy: {
      '/api/oauth/': {
        ws: false,
        target: 'https://gw.cssh.dl.cn',
        changeOrigin: true,
        secure: false,
      },
      '/api/v2/': {
        ws: false,
        target: 'https://gw.cssh.dl.cn',
        changeOrigin: true,
        secure: false,
      },
      '/api/': {
        ws: false,
        target: process.env.VUE_APP_BASE_URL,
        changeOrigin: true,
        secure: false,
      },
    },
  },

  chainWebpack(config) {
    // 提升首屏速度
    config.plugin('preload-index').tap(() => [
      {
        rel: 'preload',
        fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
        include: 'initial',
      },
    ])
    // 有过多页面会造成无意义请求
    config.plugins.delete('prefetch-index')
    // 生产配置
    config.when(process.env.NODE_ENV == 'production', (config) => {
      // 不将runtime.js单独拆包，直接写入html
      config
        .plugin('ScriptExtHtmlWebpackPlugin')
        .after('html')
        .use('script-ext-html-webpack-plugin', [
          {
            inline: /runtime\..*\.js$/,
          },
        ])
        .end()
      // 代码分隔
      // config.optimization.splitChunks({
      //   chunks: 'all', // 必须三选一： "initial"(同步包) | "all"(推荐，同步或异步包) | "async" (默认就是async，异步包)
      //   // minSize: 20000,// 字节 引入的文件大于20kb才进行分割
      //   // maxSize: 0,
      //   // minChunks: 1,// 模块至少使用次数
      //   // maxAsyncRequests: 5,// 同时加载的模块数量最多是5个，只分割出同时引入的前5个文件
      //   automaticNameDelimiter: '~', // 打包分隔符
      //   // name: true,
      //   name: function (module, chunks, cacheGroupKey) {
      //     const moduleFileName = module
      //       .identifier()
      //       .split('/')
      //       .reduceRight((item) => item)
      //     const allChunksNames = chunks.map((item) => item.name).join('~')
      //     return `${moduleFileName}`
      //   },
      //   cacheGroups: {
      //     vant: {
      //       name: 'chunk-vant',
      //       priority: 20,
      //       test: /[\\/]node_modules[\\/]_?vant(.*)/,
      //       reuseExistingChunk: true, // 模块嵌套引入时，判断是否复用已经被打包的模块
      //       enforce: true, // 忽略全局配置
      //     },
      //     vendor: {
      //       name: 'chunk-vendor',
      //       test: /[\\/]node_modules[\\/]/,
      //       priority: 10,
      //       reuseExistingChunk: true,
      //       enforce: true,
      //     },
      //     commons: {
      //       name: 'chunk-commons',
      //       test: resolve('src/components'),
      //       minChunks: 3,
      //       priority: 5,
      //       reuseExistingChunk: true,
      //       enforce: true,
      //     },
      //   },
      // })
      // 提取公共runtime
      // config.optimization.runtimeChunk('single')
    })
  },

  configureWebpack: (config) => {
    // 别名
    config.resolve.alias = {
      '@': resolve('src'),
    }
    // 生产配置
    if (process.env.NODE_ENV === 'production') {
      // 手动写入
      changeHtmlWebpackPluginChunks(config)
      //webpack 的性能提示
      config.performance = {
        hints: 'warning',
        //入口起点的最大体积
        maxEntrypointSize: 60000000,
        //生成文件的最大体积
        maxAssetSize: 40000000,
        //只给出 js 文件的性能提示
        assetFilter: function (assetFilename) {
          return assetFilename.endsWith('.js')
        },
      }
      // 移除 console.*
      config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true

      const plugins = [
        // 压缩后需要nginx配置中http模块内添加“gzip_static on”
        new CompressionWebpackPlugin({
          filename: '[path].gz[query]',
          algorithm: 'gzip',
          test: productionGzipExtensions,
          threshold: 10240, // 超过10k数据
          minRatio: 0.8,
        }),
        // 复制资源
        /*new CopyWebpackPlugin([
                            {
                                from: './src/backups',
                                to: './backups',
                            },
                        ]),*/
        // 打包分析
        new BundleAnalyzerPlugin({
          //  可以是`server`，`static`或`disabled`。
          //  在`server`模式下，分析器将启动HTTP服务器来显示软件包报告。
          //  在“静态”模式下，会生成带有报告的单个HTML文件。
          //  在`disabled`模式下，你可以使用这个插件来将`generateStatsFile`设置为`true`来生成Webpack Stats JSON文件。
          analyzerMode: 'disabled',
          //  将在“服务器”模式下使用的主机启动HTTP服务器。
          analyzerHost: '127.0.0.1',
          //  将在“服务器”模式下使用的端口启动HTTP服务器。
          analyzerPort: 8888,
          //  路径捆绑，将在`static`模式下生成的报告文件。
          //  相对于捆绑输出目录。
          reportFilename: 'report.html',
          //  模块大小默认显示在报告中。
          //  应该是`stat`，`parsed`或者`gzip`中的一个。
          //  有关更多信息，请参见“定义”一节。
          defaultSizes: 'parsed',
          //  在默认浏览器中自动打开报告
          openAnalyzer: false,
          //  如果为true，则Webpack Stats JSON文件将在bundle输出目录中生成
          generateStatsFile: false,
          //  如果`generateStatsFile`为`true`，将会生成Webpack Stats JSON文件的名字。
          //  相对于捆绑输出目录。
          statsFilename: 'stats.json',
          //  stats.toJson（）方法的选项。
          //  例如，您可以使用`source：false`选项排除统计文件中模块的来源。
          //  在这里查看更多选项：https：  //github.com/webpack/webpack/blob/webpack-1/lib/Stats.js#L21
          statsOptions: null,
          logLevel: 'info',
          // 日志级别。可以是'信息'，'警告'，'错误'或'沉默'。
        }),
      ]
      config.plugins = [...config.plugins, ...plugins]
    }
  },
}
